/* eslint-disable func-style */
/**
 * @typedef {"warn" | "error" | "info" |"debug" | "log"} LoggerKind
 * @typedef {{warn: (...args: unknown[]) => void; error: (...args: unknown[]) => void; info: (...args: unknown[]) => void; debug: (...args: unknown[]) => void; log: (...args: unknown[]) => void}} MyLog
 */

/**
 * @param {ng.ILogService} $delegate
 * @returns {MyLog}
 */
function decorateLogger($delegate) {
  /**
   * @type {LoggerKind[]}
   */
  const loggerMethod = ["log", "debug", "info", "warn", "error"];
  for (const o of loggerMethod) {
    // like decorator
    $delegate[o] = loggerDecorator($delegate[o]);
  }
  // 这里需要返回原委托者
  return $delegate;

  /**
   * @param {(...args: unknown[]) => void} originalFn
   * @returns {ng.ILogCall}
   */
  function loggerDecorator(originalFn) {
    return (() => {
      /**
       * @type {ng.ILogCall}
       */
      const logger = function logger(...args) {
        args.unshift(new Date().toLocaleString());
        // eslint-disable-next-line prefer-spread
        originalFn.apply(null, args);
      };

      logger.logs = /**
       * @type {string[]}
       */ ([]);
      return logger;
    })();
  }
}
decorateLogger.$inject = ["$delegate"];

/**
 * @param {ng.auto.IProvideService} $provide
 * @returns {void}
 */
export const myLogConfig = ($provide) => {
  $provide.decorator("$log", decorateLogger);
};

myLogConfig.$inject = ["$provide"];
